"// Generates an irradiance cube from an environment map using convolution\n"
"\n"
"#ifndef NUM_PHI_SAMPLES\n"
"#   define NUM_PHI_SAMPLES 64\n"
"#endif\n"
"\n"
"#ifndef NUM_THETA_SAMPLES\n"
"#   define NUM_THETA_SAMPLES 32\n"
"#endif\n"
"\n"
"TextureCube  g_EnvironmentMap;\n"
"SamplerState g_EnvironmentMap_sampler;\n"
"\n"
"void main(in float4 Pos      : SV_Position,\n"
"          in float3 WorldPos : WORLD_POS,\n"
"          out float4 Color   : SV_Target)\n"
"{\n"
"    float3 N     = normalize(WorldPos);\n"
"    float3 up    = float3(0.0, 1.0, 0.0);\n"
"    float3 right = normalize(cross(up, N));\n"
"    up = cross(N, right);\n"
"\n"
"    const float PI         = 3.14159265;\n"
"    const float deltaPhi   = 2.0 * PI / float(NUM_PHI_SAMPLES);\n"
"    const float deltaTheta = 0.5 * PI / float(NUM_THETA_SAMPLES);\n"
"\n"
"    float3 color = float3(0.0, 0.0, 0.0);\n"
"    float sampleCount = 0.0;\n"
"    for (int p=0; p < NUM_PHI_SAMPLES; ++p)\n"
"    {\n"
"        float phi = float(p) * deltaPhi;\n"
"        for (int t=0; t < NUM_THETA_SAMPLES; ++t)\n"
"        {\n"
"            float theta = float(t) * deltaTheta;\n"
"            float3 tempVec   = cos(phi) * right + sin(phi) * up;\n"
"            float3 sampleDir = cos(theta) * N + sin(theta) * tempVec;\n"
"            color += g_EnvironmentMap.Sample(g_EnvironmentMap_sampler, sampleDir).rgb * cos(theta) * sin(theta);\n"
"            sampleCount += 1.0;\n"
"        }\n"
"    }\n"
"    Color = float4(PI * color / sampleCount, 1.0);\n"
"}\n"
